package com.wh.wisdomsite.xbox.server.controller.workflow;

import com.wh.wisdomsite.xbox.common.Constants;
import com.wh.wisdomsite.xbox.common.reponse.CommonResult;
import com.wh.wisdomsite.xbox.common.util.ResManager;
import com.wh.wisdomsite.xbox.hkws.entity.DeploymentModel;
import com.wh.wisdomsite.xbox.hkws.entity.ProcessDefinitionModel;
import com.wh.wisdomsite.xbox.pojo.workflow.DeploymentIn;
import com.wh.wisdomsite.xbox.pojo.workflow.ProcessDefinitionIn;
import com.wh.wisdomsite.xbox.utils.IpUtils;
import com.wh.wisdomsite.xbox.utils.StringUtils;
import com.wh.wisdomsite.xbox.utils.date.DateTool;
import com.wh.wisdomsite.xbox.utils.json.JsonUtil;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * 工作流程部署管理controller
 * @author 谢泽鹏
 * @version V1.0
 * @Package com.wh.wisdomsite.xbox.server.controller.wo
 * @date 2018年09月21日 9:25
 * @Copyright 企业版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2018
 */
@Controller
@RequestMapping(value = "/deployment")
public class DeploymentController {

    private static final Log logger = LogFactory.getLog(DeploymentController.class);

    @Resource
    private RepositoryService repositoryService;


    /**
     * 跳转至部署管理页面
     * @return
     */
    @RequiresPermissions("rules:workflow_deployment_page")
    @RequestMapping(value = "/index.do", method = RequestMethod.GET)
    public String index() {
        return "workflow/deployment/deploymentList";
    }


    /**
     * 获取流程部署对象信息
     * @param response
     */
    @RequiresPermissions("rules:workflow_deployment_find")
    @RequestMapping(value = "/deploymentList.do")
    public void deploymentList(HttpServletResponse response, DeploymentIn in) {
        JSONArray jsonArray = new JSONArray();
        JSONObject json = new JSONObject();
        try{
            //设置分页
            if(in.getPage() == 1) in.setPage(0);
            if(in.getRows() == 10) in.setRows(9);
            logger.info("获取流程部署信息->>开始");
            List<Deployment> deploymentAll = repositoryService.createDeploymentQuery().list();
            List<Deployment> deployments  = repositoryService.createDeploymentQuery().orderByDeploymenTime().desc().listPage(in.getPage(), in.getRows());
            for(Deployment deployment : deployments){
                DeploymentModel deploymentModel = new DeploymentModel();
                deploymentModel.setId(deployment.getId());
                deploymentModel.setName(deployment.getName());
                deploymentModel.setDeploymentTime(DateTool.format(deployment.getDeploymentTime(), "yyyy-MM-dd HH:mm:ss"));
                JSONObject object = new JSONObject(deploymentModel);
                jsonArray.put(object);
            }
            json.put("total", deploymentAll.size());
            json.put("rows", jsonArray);
            ResManager.getTextOut(response).print(json);
            logger.info("获取流程部署信息->>结束");

        } catch (Exception e){
            e.printStackTrace();
            logger.error("获取流程部署信息->Exception " + e.getMessage());
        }
    }


    /**
     * 获取流程定义信息
     * @param response
     */
    @RequiresPermissions("rules:workflow_processDefinition_find")
    @RequestMapping(value = "/processDefinitionList.do")
    public void processDefinitionList(HttpServletResponse response, ProcessDefinitionIn in) {
        JSONArray jsonArray = new JSONArray();
        JSONObject json = new JSONObject();
        try{
            logger.info("获取流程定义信息->>开始");
            List<ProcessDefinition> processDefinitionAll = null;
            List<ProcessDefinition> processDefinitions = null;
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            if(StringUtils.isNotEmpty(in.getDeploymentId())){
                processDefinitionQuery.deploymentId(in.getDeploymentId());
            }
            processDefinitionAll = processDefinitionQuery.list();
            processDefinitions = processDefinitionQuery.orderByProcessDefinitionVersion().desc().list();
            for(ProcessDefinition processDefinition : processDefinitions){
                ProcessDefinitionModel processDefinitionModel = new ProcessDefinitionModel();
                processDefinitionModel.setId(processDefinition.getId());
                processDefinitionModel.setCategory(processDefinition.getCategory());
                processDefinitionModel.setName(processDefinition.getName());
                processDefinitionModel.setKey(processDefinition.getKey());
                processDefinitionModel.setVersion(processDefinition.getVersion());
                processDefinitionModel.setDeploymentId(processDefinition.getDeploymentId());
                processDefinitionModel.setResourceName(processDefinition.getResourceName());
                processDefinitionModel.setDiagramResourceName(processDefinition.getDiagramResourceName());
                processDefinitionModel.setDescription(processDefinition.getDescription());
                processDefinitionModel.setTenantId(processDefinition.getTenantId());
                JSONObject object = new JSONObject(processDefinitionModel);
                jsonArray.put(object);
            }
            json.put("total", processDefinitionAll.size());
            json.put("rows", jsonArray);
            ResManager.getTextOut(response).print(json);
            logger.info("获取流程定义信息->>结束");
        } catch (Exception e){
            e.printStackTrace();
            logger.error("获取流程定义信息->Exception " + e.getMessage());
        }
    }




    /**
     * 跳转至部署流程定义
     * @return
     */
    @RequestMapping("/toDeployment")
    public String toDeployment(){
        return "workflow/deployment/addDeployment";
    }


    /**
     * 部署流程定义
     * @param fileName
     * @param response
     */
    @RequiresPermissions("rules:workflow_deployment_edit")
    @RequestMapping(value = "/addDeployment.do", method = RequestMethod.POST)
    public void addDeployment(@RequestParam(value = "file") MultipartFile file, String fileName, HttpServletResponse response, HttpServletRequest request){
        CommonResult result = new CommonResult();
        try {
            logger.info("部署流程定义->>开始");
            if(StringUtils.isEmpty(fileName)){
                result.setCode(Constants.CODE_FAIL);
                result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_FILENAME_NOT_EMPTY);
                sysPrintByContentType(response, request, result);
                return;
            }
            if(null == file){
                result.setResult(Constants.CODE_FAIL);
                result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_FILE_NOT_EMPTY);
                sysPrintByContentType(response, request, result);
                return;
            }
            ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream());
            repositoryService.createDeployment().name(fileName).addZipInputStream(zipInputStream).deploy();
            result.setResult(Constants.CODE_SUCCESS);
            result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_SUCCESS);
            logger.info("部署流程定义->>结束");
        } catch (Exception e) {
            e.printStackTrace();
            result.setResult(Constants.CODE_FAIL);
            result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_FAIL);
            logger.error("部署流程定义->>Exception " + e.getMessage());
        }
            sysPrintByContentType(response, request, result);

    }


    /**
     * 删除流程定义
     * @param in
     * @param response
     */
    @RequiresPermissions("rules:workflow_deployment_del")
    @RequestMapping(value = "/delDeployment.do", method = RequestMethod.GET)
    public void delDeployment(DeploymentIn in, HttpServletResponse response){
        CommonResult result = new CommonResult();
        try {
            logger.info("删除流程定义->>开始");
            repositoryService.deleteDeployment(in.getId(), true);
            result.setCode(Constants.CODE_SUCCESS);
            result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_DEL_SUCCESS);
            logger.info("删除流程定义->>结束");
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(Constants.CODE_FAIL);
            result.setMessage(Constants.ZHGD_WORKFLOW_DEPLOYMENT_DEL_FAIL);
            logger.error("删除流程定义->>Exception " + e.getMessage());
        }
            ResManager.getJsonOut(response).print(JsonUtil.Json2All(result));

    }

    /**
     * 跳转至部署流程定义
     * @return
     */
    @RequestMapping("/toViewImage")
    public String toViewImage(HttpServletRequest request, ProcessDefinitionIn in){
        request.setAttribute("deploymentId", in.getDeploymentId());
        request.setAttribute("diagramResourceName", in.getDiagramResourceName());
        return "workflow/deployment/currentView";
    }


    /**
     * 查看流程土
     * @param in
     * @param response
     */
    @RequiresPermissions("rules:workflow_deployment_view")
    @RequestMapping(value = "/viewImage.do", method = RequestMethod.GET)
    public void viewImage(ProcessDefinitionIn in, HttpServletResponse response){
        try {
            logger.info("查看流程图->>开始");
            //资源图片输入流InputStream
            InputStream inputStream = repositoryService.getResourceAsStream(in.getDeploymentId(), in.getDiagramResourceName());
            //从response对象获取输出流
            OutputStream out = response.getOutputStream();
            //将输入流中的数据读取出来，写到输出流中
            for(int b = -1; (b = inputStream.read()) != -1;){
                out.write(b);
            }
            out.close();
            inputStream.close();
            logger.info("查看流程图->>结束");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("查看流程图->>Exception " + e.getMessage());
        }
    }






    /**
     * 向客户端输出
     * @param response
     * @param request
     * @param result
     */
    public void sysPrintByContentType(HttpServletResponse response, HttpServletRequest request, CommonResult result){
        if(IpUtils.isIE(request)){
            ResManager.getTextOut(response).print("{'code': '" + result.getCode()  + "', 'message': '" + result.getMessage() + "', 'result': {}}");
        }else{
            ResManager.getJsonOut(response).print(JsonUtil.Json2All(result));
        }

    }










}
